package com.coderman.basketball.infrast.mq;

import com.coderman.basketball.infrast.mq.annotation.MqConsumer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * Description:
 * date: 2021/5/25
 *
 * @author shenshuai
 * @version 1.0.0
 * @since JDK 1.8
 */
@Service
@Slf4j
public class MqConsumeHandlerContainer implements ApplicationContextAware {
    /**
     * 存储消息消费的事件处理器
     */
    private static Map<String, MqConsumeHandler> mqHandlerMap = new HashMap<>();

    /**
     * 根据topic#tag，返回对应的消息事件handler
     *
     * @param handleKey
     * @return
     */
    public MqConsumeHandler getMessageHandler(String handleKey) {
        return mqHandlerMap.get(handleKey);
    }

    /**
     * 重写ApplicationContextAware的方法，将MQ handler和起对应的tag进行绑定，并存入map中
     * @param applicationContext
     * @throws BeansException
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        Map<String, Object> beansOfMQHandler = applicationContext.getBeansWithAnnotation(MqConsumer.class);
        for (Map.Entry<String, Object> entry : beansOfMQHandler.entrySet()) {
            // 获取Handler中的topic#tag作为key，与 handler作为value，放入到map中，组成key value的模式
            MqConsumer identifier = AopUtils.getTargetClass(entry.getValue()).getAnnotation(MqConsumer.class);
            String handleKey = identifier.topic() + "#" + identifier.msgTag();
            mqHandlerMap.put(handleKey, (MqConsumeHandler) entry.getValue());
        }
        log.info(">>>>>MQ消息处理handler容器，topic&tag:{}", mqHandlerMap);
    }
}
